import json
from datetime import datetime

from django import http
from django.shortcuts import render
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django_redis import get_redis_connection

from goods.models import SKU, GoodsCategory, CategoryVisitCount
from django.core.paginator import Paginator

# Create your views here.
from meiduo_mall.utils import constants
from meiduo_mall.utils.my_category import get_categories
from meiduo_mall.utils.my_loginview import LoginRequiredView
from meiduo_mall.utils.response_code import RET


class ListView(View):

    def get(self, request, category_id, page):

        # 排序
        sort = request.GET.get('sort', 'default')

        # 0,1 根据sort,设置数据库查询的排序字段; sort给前端显示用的, sort_field数据排序查询用的
        if sort == "price":
            sort_field = "-price"
        elif sort == "hot":
            sort_field = "-sales"
        else:
            sort_field = "-create_time"

        # 获取分类数据
        categories = get_categories()

        # 查询SKUS数据
        skus = SKU.objects.filter(category_id=category_id).order_by(sort_field).all()

        # 分页
        paginator = Paginator(object_list=skus, per_page=constants.SKU_LIST_PAGE_COUNT)
        paginate = paginator.page(page)
        sku_list = paginate.object_list
        current_page = paginate.number
        total_page = paginator.num_pages
        # 获取分类对象
        category = GoodsCategory.objects.get(id=category_id)

        context = {
            'categories': categories,
            'skus': sku_list,
            'category': category,
            'current_page': current_page,
            'total_page': total_page,
            'sort': sort,

        }
        return render(request, 'list.html', context=context)


class HotSkuView(View):
    def get(self, request, category_id):
        # 根据分类编号获取skus数据
        skus = SKU.objects.filter(category_id=category_id).all()[:constants.SKU_HOT_COUNT]

        hot_sku_list = [{'name': sku.name, 'price': sku.price, 'default_image_url': sku.default_image_url.url} for sku in skus]
        print(hot_sku_list)
        return http.JsonResponse({'hot_sku_list': hot_sku_list})


class SKUDetailView(View):

    def get(self, request, sku_id):

        # 获取商品分类
        categories = get_categories()

        sku = SKU.objects.get(id=sku_id)
        category = sku.category

        # 3, 商品规格信息
        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 拼接数据
        context = {
            "categories": categories,
            "category": category,
            "sku": sku,
            "specs": goods_specs
        }

        return render(request, 'detail.html', context=context)


# 商品分类访问量
class CategoryVisitCountView(View):

    @csrf_exempt
    def post(self, request, category_id):
        today = datetime.today()

        # 2, 查询分类访问量对象
        try:
            category_visit_count = CategoryVisitCount.objects.get(date=today, category_id=category_id)
        except Exception as e:
            category_visit_count = CategoryVisitCount()

        # 3, 设置访问数据,入库
        category_visit_count.date = today
        category_visit_count.category_id = category_id
        category_visit_count.count += 1
        category_visit_count.save()

        # 4, 返回响应
        return http.JsonResponse({"code": RET.OK})


class BrowseHistoryView(LoginRequiredView):

    @csrf_exempt
    def post(self, request):
        # 1,获取参数
        dict_data = json.loads(request.body.decode())
        sku_id = dict_data.get("sku_id")

        # 2,校验参数
        if not sku_id:
            return http.JsonResponse({"code":RET.PARAMERR})

        # 3,数据入库(redis)
        # 3,1 去重
        redis_conn = get_redis_connection('history')
        redis_conn.lrem('history_%s' % request.user.id, 0, sku_id)

        # 存储
        redis_conn.lpush('history_%s' % request.user.id, sku_id)

        # 截取
        redis_conn.ltrim('history_%s' % request.user.id, 0, 4)

        # 4,返回响应
        return http.JsonResponse({"code": RET.OK})

    def get(self, request):
        redis_conn = get_redis_connection('history')

        sku_ids = redis_conn.lrange('history_%s' % request.user.id, 0, -1)
        print(sku_ids, type(sku_ids))
        sku_list = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            sku_dict = {
                'default_image_url': sku.default_image_url.url,
                'name': sku.name,
                'price': sku.price,
                'id': sku.id,
            }
            sku_list.append(sku_dict)
        return http.JsonResponse({'skus': sku_list, 'code': RET.OK})